﻿using System.IO;
using System.IO.IsolatedStorage;

namespace Gmantis.Uploader
{
    public class UploadFileInfo
    {
        // Fields
        private FileInfo _file;
        private string _fileName;
        private bool _isPrepared;
        private string _name;
        private Stream _stream;
        private FileInfoType _type;

        // Methods
        public UploadFileInfo(FileInfo file)
        {
            this._type = FileInfoType.FileDialog;
            this._file = file;
        }

        public UploadFileInfo(string fileName)
        {
            this._type = FileInfoType.IsolatedStorage;
            this._fileName = fileName;
        }

        public UploadFileInfo(string name, Stream file)
        {
            this._type = FileInfoType.Stream;
            this._name = name;
            this._stream = file;
        }

        public void Close()
        {
            if (((this._type == FileInfoType.FileDialog) || (this._type == FileInfoType.IsolatedStorage)) && this._isPrepared)
            {
                this._stream.Close();
                this._isPrepared = false;
            }
        }

        public long GetSize()
        {
            if (this._isPrepared)
            {
                return this._stream.Length;
            }
            return 0L;
        }

        public void Prepare()
        {
            if (!this._isPrepared)
            {
                switch (this._type)
                {
                    case FileInfoType.FileDialog:
                        this._name = this._file.Name;
                        this._stream = this._file.OpenRead();
                        this._isPrepared = true;
                        return;

                    case FileInfoType.IsolatedStorage:
                        this._name = Path.GetFileName(this._fileName);
                        this._stream = IsolatedStorageFile.GetUserStoreForApplication().OpenFile(this._fileName, FileMode.Open);
                        this._isPrepared = true;
                        return;

                    case FileInfoType.Stream:
                        if (this._stream.CanSeek)
                        {
                            this._stream.Seek(0L, SeekOrigin.Begin);
                        }
                        this._isPrepared = true;
                        break;

                    default:
                        return;
                }
            }
        }

        // Properties
        public Stream File
        {
            get
            {
                return this._stream;
            }
        }

        public string Name
        {
            get
            {
                switch (this._type)
                {
                    case FileInfoType.FileDialog:
                        return this._file.Name;

                    case FileInfoType.IsolatedStorage:
                        return this._fileName;

                    case FileInfoType.Stream:
                        return this._name;
                }
                return this._name;
            }
        }

        // Nested Types
        private enum FileInfoType
        {
            FileDialog,
            IsolatedStorage,
            Stream
        }
    }
}
